<?php

namespace app\keeper\controller;

use app\common\lib\Str;
use app\common\model\mysql\AllotLibrary;
use app\common\model\mysql\AllotLibraryProduct;
use app\common\model\mysql\In;
use app\common\model\mysql\InProduct;
use app\common\model\mysql\Out;
use app\common\model\mysql\OutProduct;
use app\common\model\mysql\WarehouseSpace;
use app\common\model\mysql\WarehouseSpaceProduct;
use app\common\model\mysql\Product;
use app\common\model\mysql\Worker;
use app\common\model\mysql\Warehouse;
use think\facade\Db;

class Transfers extends AuthBase
{
    /**
     * 店内调拨
     * @return \think\response\Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function transfers(){
        $warehouse_out_id = $this->request->param('warehouse_out_id');
        $warehouse_into_id = $this->request->param('warehouse_into_id');
        if(empty($warehouse_out_id)){
            return show(config("status.error"),"缺少参数调出库id");
        }
        if(empty($warehouse_into_id)){
            return show(config("status.error"),"缺少参数调入库id");
        }
        $remark = $this->request->param('remark');
        //调拨商品：product_id，count，typeenum
        $goodsData = $this->request->param('goodsData');
        if(empty($goodsData)){
            return show(config("status.error"),"缺少参数商品数据");
        }
        foreach($goodsData as $key=>$value){
            if(!array_key_exists('product_id', $value) || !array_key_exists('count', $value) || !array_key_exists('typeenum', $value)) {
                return show(config("status.error"), "商品数据传输有误");
            }
            $productData = (new Product())->getProductFind([['product_id','=',$value['product_id']],['isdel','=','0']],'product_name,price_unit,tcount');

            $WsWhere = [
                ['warehouse_id','=',$warehouse_into_id],
                ['isdel','=','0']
            ];
            $warehouseIntoSpaceData = (new WarehouseSpace())->getNormalWarehouseSpaceFind($WsWhere,'warehouse_space_id');
            $goodsData[$key]['warehouse_into_space_id'] = $warehouseIntoSpaceData['warehouse_space_id'];
            $WspWhere = [
                ['a.warehouse_id','=',$warehouse_out_id],
                ['a.product_id','=',$value['product_id']],
                ['a.isdel','=','0']
            ];
            $warehouseSpaceProduct = (new WarehouseSpaceProduct())->getNormalWarehouseSpaceProductFind($WspWhere,'a.warehouse_space_id,a.tcount');
            if(empty($warehouseSpaceProduct)){
                return show(config("status.error"),"仓位下未找到商品名为“".$productData['product_name']."”的商品");
            }
            if($warehouseSpaceProduct['tcount']<$value['count']){
                return show(config("status.error"),"商品名为“".$productData['product_name']."”的商品调出库数量不能大于该仓位下商品数量");
            }
            $goodsData[$key]['warehouse_out_space_id'] = $warehouseSpaceProduct['warehouse_space_id'];
            $goodsData[$key]['product_name'] = $productData['product_name'];
            $goodsData[$key]['price_unit'] = $productData['price_unit'];
            $goodsData[$key]['tcount'] = $productData['tcount'];
        }
        try {
            Db::startTrans(); // 开始事务
            $allotAdd['warehouse_into_id'] = $warehouse_into_id;
            $allotAdd['warehouse_out_id'] = $warehouse_out_id;
            $allotAdd['order_sn'] = (new Str())->makeOrderNo($this->shopId,5);
            $allotAdd['adddate'] = date("Y-m-d H:i:s",time());
            $allotAdd['remark'] = $remark;
            $allotAdd['company_id'] = $this->companyId;
            $allotAdd['shop_id'] = $this->shopId;
            $allotAdd['worker_id'] = $this->workerId;
            $allotAdd['worker_name'] = $this->workerName;
            $allotRes = (new AllotLibrary())->addAllotLibraryData($allotAdd);
            if(empty($allotRes)){
                return show(config("status.error"),"调拨失败");
            }
            $total_amount = 0;
            foreach($goodsData as $key=>$value){
                $inproduct[$key]['allot_library_id'] = $allotRes;
                $inproduct[$key]['warehouse_spaceid_out'] = $value['warehouse_out_space_id'];
                $inproduct[$key]['warehouse_spaceid_into'] = $value['warehouse_into_space_id'];
                $inproduct[$key]['product_id'] = $value['product_id'];
                $inproduct[$key]['product_name'] = $value['product_name'];
                $inproduct[$key]['tcount'] = $value['count'];
                $inproduct[$key]['pmoney'] = $value['price_unit'];
                $inproduct[$key]['producttypeenum'] = $value['typeenum'];
                $total_amount += $value['price_unit']*$value['count'];

                $warehouseSpaceProductWhere = [
                    ['warehouse_id','=',$warehouse_out_id],
                    ['warehouse_space_id','=',$value['warehouse_out_space_id']],
                    ['product_id','=',$value['product_id']],
                    ['isdel','=','0']
                ];
                (new WarehouseSpaceProduct())->saveDecWarehouseSpaceProductField($warehouseSpaceProductWhere,'tcount',$value['count']);

                //添加出库单
                $outData = (new Out())->getOutFind([['modelid','=',$allotRes],['modeltypeenum','=',9]],'id');
                if($outData){
                    $outRes = $outData['id'];
                }else{
                    $outAdd['company_id'] = $this->companyId;
                    $outAdd['shop_id'] = $this->shopId;
                    $outAdd['order_sn'] = (new Str())->makeOrderNo($this->shopId,7);
                    $outAdd['worker_id'] = $this->workerId;
                    $outAdd['worker_name'] = $this->workerName;
                    $outAdd['adddate'] = date("Y-m-d H:i:s",time());
                    $outAdd['note'] = "";
                    $outAdd['outtypeenum'] = 16;
                    $outAdd['modeltypeenum'] = 9;
                    $outAdd['modelid'] = $allotRes;
                    $outRes = (new Out())->addOutData($outAdd);
                }
                //出库单产品
                $outGoods[$key]['out_id']           = $outRes;
                $outGoods[$key]['warehouse_id']     = $warehouse_out_id;
                $outGoods[$key]['warehouse_space_id'] = $value['warehouse_out_space_id'];
                $outGoods[$key]['product_id']       = $value['product_id'];
                $outGoods[$key]['tcount']           = $value['count'];
                $outGoods[$key]['price_unit']       = $value['price_unit'];
                $outGoods[$key]['producttypeenum']  = $value['typeenum'];
                $outGoods[$key]['count_after']      = $value['tcount']+$value['count'];
                $outGoods[$key]['count_before']     = $value['tcount'];
                $outGoods[$key]['adddate']          = date("Y-m-d H:i:s",time());

                $warehouseSpaceProductWhere = [
                    ['a.warehouse_id','=',$warehouse_into_id],
                    ['a.warehouse_space_id','=',$value['warehouse_into_space_id']],
                    ['a.product_id','=',$value['product_id']],
                    ['a.isdel','=','0']
                ];
                $intoPassData = (new WarehouseSpaceProduct())->getNormalWarehouseSpaceProductFind($warehouseSpaceProductWhere,"*");
                if($intoPassData){
                    $warehouseSpaceProductWhere = [
                        ['warehouse_id','=',$warehouse_into_id],
                        ['warehouse_space_id','=',$value['warehouse_into_space_id']],
                        ['product_id','=',$value['product_id']],
                        ['isdel','=','0']
                    ];
                    (new WarehouseSpaceProduct())->saveInWarehouseSpaceProductField($warehouseSpaceProductWhere,'tcount',$value['count']);
                }else{
                    $space['warehouse_id']         = $warehouse_into_id;
                    $space['warehouse_space_id']   = $value['warehouse_into_space_id'];
                    $space['product_id']           = $value['product_id'];
                    $space['tcount']               = $value['count'];
                    $space['company_id']           = $this->companyId;
                    $space['shop_id']              = $this->shopId;
                    $space['isdel']                = '0';
                    (new WarehouseSpaceProduct())->addWarehouseSpaceProductData($space);
                }
                //添加出库单
                $inData = (new In())->getInFind([['modelid','=',$allotRes],['modeltypeenum','=',9]],'id');
                if($inData){
                    $inRes = $inData['id'];
                }else{
                    $inAdd['company_id'] = $this->companyId;
                    $inAdd['shop_id'] = $this->shopId;
                    $inAdd['warehouse_id'] = $warehouse_into_id;
                    $inAdd['order_sn'] = (new Str())->makeOrderNo($this->shopId,6);
                    $inAdd['worker_id'] = $this->workerId;
                    $inAdd['worker_name'] = $this->workerName;
                    $inAdd['adddate'] = date("Y-m-d H:i:s",time());
                    $inAdd['note'] = "";
                    $inAdd['intypeenum'] = 16;
                    $inAdd['modeltypeenum'] = 9;
                    $inAdd['modelid'] = $allotRes;
                    $inRes = (new In())->addInData($inAdd);
                }
                //入库单产品
                $inGoods[$key]['in_id']             = $inRes;
                $inGoods[$key]['warehouse_id']      = $warehouse_into_id;
                $inGoods[$key]['warehouse_space_id']= $value['warehouse_into_space_id'];
                $inGoods[$key]['product_id']        = $value['product_id'];
                $inGoods[$key]['tcount']            = $value['count'];
                $inGoods[$key]['price_unit']        = $value['price_unit'];
                $inGoods[$key]['producttypeenum']   = $value['typeenum'];
                $inGoods[$key]['count_after']       = $value['tcount']+$value['count'];
                $inGoods[$key]['count_before']      = $value['tcount'];
                $inGoods[$key]['adddate']           = date("Y-m-d H:i:s",time());
            }
            (new AllotLibraryProduct())->addAllAllotLibraryProduct($inproduct);
            $allotSaveData['total_amount'] = $total_amount;
            (new AllotLibrary())->saveAllotLibraryData($allotRes,$allotSaveData);
            (new InProduct())->addAllInProduct($inGoods);
            (new OutProduct())->addAllOutProduct($outGoods);
            // 提交事务
            Db::commit();
            return show(config('status.success'), "调拨成功", ['success'=>200]);
        }catch (\Exception $e){
            // 回滚事务
            Db::rollback();
            return show(config("status.error"),$e->getMessage());
        }
    }

    /**
     * 店内调拨历史列表
     * @return \think\response\Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function transfersHistory(){
        $page = $this->request->param('pageNum', 1);//当前页
        $limit = $this->request->param('pageSize', 10);//每页显示条数
        if(empty($page) || empty($limit)){
            return show(config("status.error"),"缺少分页参数");
        }
        $where = [
            ['shop_id','=',$this->shopId],
            ['isdel','=','0']
        ];
        $field = "id as allot_library_id,warehouse_into_id,warehouse_out_id,order_sn,adddate,total_amount,worker_id";
        $historyList = (new AllotLibrary())->getNormalAllotLibraryList($where,$limit,$page,$field);
        $workerDb = (new Worker());
        $warehouseDb =  (new Warehouse());
        $allotLibraryProductDb = (new AllotLibraryProduct());
        // 处理结果数据，确保日期字段不为null
        foreach ($historyList['data'] as &$item) {
            $warehouseIntoData = $warehouseDb->getNormalWarehouseFind([['warehouse_id','=',$item['warehouse_into_id']]],'warehouse_name');
            $item['warehouse_into_name'] = $warehouseIntoData['warehouse_name'];
            $warehouseOutData = $warehouseDb->getNormalWarehouseFind([['warehouse_id','=',$item['warehouse_out_id']]],'warehouse_name');
            $item['warehouse_out_name'] = $warehouseOutData['warehouse_name'];
            $item['count'] = $allotLibraryProductDb->getNormalAllAllotLibraryProductSum([['allot_library_id','=',$item['allot_library_id']]]);
            $item['tname'] = $workerDb->getWorkerByIdFind($item['worker_id'])['tname'];
            unset($item['warehouse_into_id']);
            unset($item['warehouse_out_id']);
            unset($item['worker_id']);
        }
        return show(config("status.success"),"店内调拨历史列表",$historyList['data']);
    }

    //调拨历史详情
    public function transfersDetails(){
        $allot_library_id = $this->request->param('allot_library_id');
        if(empty($allot_library_id)){
            return show(config("status.error"),"缺少参数调拨单id");
        }
        $allotData = (new AllotLibrary())->getAllotLibraryFind([['id','=',$allot_library_id]]);
        if(empty($allotData)){
            return show(config("status.error"),"未查询到调拨单数据");
        }
        $where = [
            ['warehouse_id','=',$allotData['warehouse_into_id']]
        ];
        $WarehouseData = (new Warehouse())->getNormalWarehouseFind($where,'*');
        $allotData['warehouse_into_name'] = $WarehouseData['warehouse_name'];
        $where = [
            ['warehouse_id','=',$allotData['warehouse_out_id']]
        ];
        $WarehouseData = (new Warehouse())->getNormalWarehouseFind($where,'*');
        $allotData['warehouse_out_name'] = $WarehouseData['warehouse_name'];
        $allotData['tname'] = (new Worker())->getWorkerByIdFind($allotData['worker_id'])['tname'];
        $data = array(
            'allot_library_id'      => $allotData['id'],
            'warehouse_into_name'   => $allotData['warehouse_into_name'],
            'warehouse_out_name'    => $allotData['warehouse_out_name'],
            'tname'                 => $allotData['tname'],
            'order_sn'              => $allotData['order_sn'],
            'adddate'               => $allotData['adddate'],
            'remark'                => $allotData['remark']??'',
            'total_amount'          => $allotData['total_amount'],
        );
        $pWhere = [
            ['a.allot_library_id','=',$allot_library_id]
        ];
        $field = "a.product_name,a.tcount as count,a.pmoney,a.producttypeenum,b.warehouse_space_name as warehouse_space_out_name,c.warehouse_space_name as warehouse_space_into_name";
        $data['allotGoodsData'] = (new AllotLibraryProduct())->getNormalAllAllotLibraryProductList($pWhere,$field);
        return show(config("status.success"),"调拨历史详情",$data);
    }
}
